package com.zxk.util;

import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.zxk.constant.OperConstants;
import com.zxk.constant.ParamConstants;
import com.zxk.constant.PicConstants;
import com.zxk.entity.FindPicResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;


/**
 * 鼠标操作工具类
 *
 * @author: 舟小亢
 * @date: 2023-08-09 21:31
 */
public class MouseUtil {

    private static Logger LOG = LoggerFactory.getLogger(MouseUtil.class);


    /**
     * 点击鼠标左键并弹起，增加随机数
     *
     * @param x
     * @param y
     * @return
     */
    public static boolean lClickRandom(WinDef.HWND hwnd, int x, int y) throws Exception {
        return click(x + new Random().nextInt(ParamConstants.RANDOM),
                y + new Random().nextInt(ParamConstants.RANDOM),
                hwnd,
                OperConstants.WM_LBUTTONDOWN,
                OperConstants.WM_LBUTTONUP,
                0);
    }

    /**
     * 点击鼠标左键并弹起
     *
     * @param x
     * @param y
     * @return
     */
    public static boolean lClick(WinDef.HWND hwnd, int x, int y) throws Exception {
        return click(x, y, hwnd, OperConstants.WM_LBUTTONDOWN, OperConstants.WM_LBUTTONUP, 0);
    }

    /**
     * 鼠标点击并弹起命令
     *
     * @param x        x
     * @param y        y
     * @param hwnd     句柄
     * @param keyDown  按下键值
     * @param keyUp    弹起键值
     * @param keyValue 按钮键值
     * @return
     */
    public static boolean click(int x, int y, WinDef.HWND hwnd, int keyDown, int keyUp, long keyValue) throws Exception {
        // 游戏顶部存在黑边，y坐标需要减掉，校准坐标精度
        x = x + ParamConstants.X_ACCURACY;
        y = y + ParamConstants.Y_ACCURACY;
        LOG.info("点击坐标x:{} y:{}", x, y);
        // 高16位为y坐标，低16位为x坐标
        long postion = (x & 0xffff) | (y & 0xffffL) << 16;
        // 激活句柄
        User32.INSTANCE.SetForegroundWindow(hwnd);
        // 发送按钮点击命令
        User32.INSTANCE.SendMessage(hwnd, keyDown, new WinDef.WPARAM(keyValue), new WinDef.LPARAM(postion));
        // 发送按钮弹起命令
        User32.INSTANCE.SendMessage(hwnd, keyUp, new WinDef.WPARAM(keyValue), new WinDef.LPARAM(postion));
        ThreadUtil.sleep1();
        return true;
    }

    /**
     * 鼠标滚轮纵向滚动
     *
     * @param hwnd
     * @param x
     * @param y
     * @param delta 正数表示下拉，负数表示上提
     * @return
     */
    public static boolean wMove(WinDef.HWND hwnd, int x, int y, int delta) throws Exception {
        ThreadUtil.sleep2();
        y = y + ParamConstants.Y_ACCURACY;
        x = x + ParamConstants.X_ACCURACY;
        LOG.info("鼠标滚动坐标x:{} y:{}", x, y);
        long postion = (x & 0xffff) | (y & 0xffffL) << 16;
        // 激活句柄
        User32.INSTANCE.SetForegroundWindow(hwnd);
        User32.INSTANCE.SendMessage(hwnd, OperConstants.WM_MOUSEWHEEL, new WinDef.WPARAM(delta << 16), new WinDef.LPARAM(postion));
        // 睡1秒，等待游戏反应
        ThreadUtil.sleep2();
        return true;
    }

    /**
     * 拖拽移动
     *
     * @param hwnd
     * @param x
     * @param y
     * @return
     */
    public static boolean dragMove(WinDef.HWND hwnd, int x, int y, int dx, int dy) throws Exception {
        ThreadUtil.sleep1();
        // 高16位为y坐标，低16位为x坐标
        y = y + ParamConstants.Y_ACCURACY;
        x = x + ParamConstants.X_ACCURACY;
        int x1 = x + dx;
        int y1 = y + dy;
        long postion = (x & 0xffff) | (y & 0xffffL) << 16;
        long postion1 = (x1 & 0xffff) | (y1 & 0xffffL) << 16;
        User32.INSTANCE.SendMessage(hwnd, OperConstants.WM_LBUTTONDOWN, new WinDef.WPARAM(0), new WinDef.LPARAM(postion));
        ThreadUtil.sleep(500);
        User32.INSTANCE.SendMessage(hwnd, OperConstants.WM_MOUSEMOVE, new WinDef.WPARAM(0), new WinDef.LPARAM(postion1));
        ThreadUtil.sleep(500);
        User32.INSTANCE.SendMessage(hwnd, OperConstants.WM_LBUTTONUP, new WinDef.WPARAM(0), new WinDef.LPARAM(postion1));
        ThreadUtil.sleep2();
        return true;
    }

}
